package br.requisiteworks.modelo.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.modelo.Cliente;
import br.requisiteworks.modelo.Projeto;
import br.requisiteworks.modelo.Time;
import br.requisiteworks.modelo.dao.ProjetoDao;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

/**
 * Implementacao JPA do {@link ProjetoDao}
 * 
 * @author Leandro Chaves
 * 
 * @version 1, 06/07/2010
 * 
 */
@Repository
public class JpaProjetoDao implements ProjetoDao {

	@PersistenceContext
	private EntityManager em;

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void insert(Projeto projeto) throws ErroBancoDados {
		try {
			em.persist(projeto);
			em.flush();
		} catch (PersistenceException e) {
			throw new ErroBancoDados("Ocorreu um erro ao adicionar projeto: "
					+ projeto, e);
		}
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void update(Projeto projeto) {
		em.merge(projeto);
		em.flush();
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void delete(Projeto projeto) {
		projeto.setRegistroAtivo(false);
		this.update(projeto);
	}

	@Override
	public Projeto select(int numero) throws ResultadoVazio {
		Projeto reference = em.find(Projeto.class, numero);

		if (reference == null) {
			throw new ResultadoVazio("Nao foi encontrado projeto de numero = "
					+ numero);
		}
		return reference;
	}

	@Override
	public List<Projeto> select(String nome) throws ResultadoVazio {
		TypedQuery<Projeto> query = em
				.createQuery(
						"SELECT DISTINCT OBJECT(c) FROM Projeto c WHERE (c.nome LIKE :nome) and c.registroAtivo=true",
						Projeto.class);
		query.setParameter("nome", "%" + nome + "%");
		List<Projeto> resultado = query.getResultList();

		if (resultado == null || resultado.isEmpty()) {
			throw new ResultadoVazio("Nao foi encontrado projeto com nome = "
					+ nome);
		}

		return resultado;
	}

	@Override
	public List<Projeto> select() throws ResultadoVazio {
		TypedQuery<Projeto> query = em
				.createQuery(
						"SELECT DISTINCT OBJECT(c) FROM Projeto c WHERE c.registroAtivo=true",
						Projeto.class);
		List<Projeto> resultado = query.getResultList();

		if (resultado == null || resultado.isEmpty()) {
			throw new ResultadoVazio(
					"Nao foi encontrado nenhum registro de projeto ativo");
		}

		return resultado;
	}

	@Override
	public List<Projeto> select(Cliente cliente) throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Projeto> select(Time time) throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}
}
